
#ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>

#else
 #include <sys/mman.h>
 
 #ifndef PAGESIZE
  #define PAGESIZE 4096
 #endif 

#endif


typedef unsigned long address_t;


typedef unsigned char my_uint8_t;
typedef unsigned short my_uint16_t;
typedef unsigned long my_uint32_t;
typedef unsigned long long my_uint64_t;

NATIVE_DECL(peek) (AMX *amx, cell *params)
{
	address_t *addr = reinterpret_cast<address_t *>(params[1]);
	return(*addr);
}

NATIVE_DECL(poke) (AMX *amx, cell *params)
{
	address_t address = (address_t) params[1];
	address_t new_value = (address_t) params[2];

	#ifdef WIN32
	address_t d, ds;
	VirtualProtect((LPVOID)address, sizeof(new_value), PAGE_EXECUTE_READWRITE, &d);
	#else // ifdef WIN32
	// it's a bit tricky for linux
	int r = address/PAGESIZE;
	char* p = (char *)(r*PAGESIZE);
	if(!mprotect( p, PAGESIZE, PROT_WRITE | PROT_READ | PROT_EXEC ) )
	#endif // ifdef WIN32
	{
		*(address_t*)(address) = new_value;
		#ifdef WIN32
		VirtualProtect((LPVOID)address, sizeof(new_value), d, &ds);
		#endif // ifdef WIN32
		return 1;
	}
	return 0;
}

NATIVE_DECL(addr_global) (AMX *amx, cell *params)
{
	cell * var;
	amx_GetAddr(amx, params[1], &var);

	return reinterpret_cast<cell>(var);
}

